/*
 * familytree.c
 *
 * Sisältää singleton sukupuun luonnin sekä funktioita sukupuuhun 
 * liittyen.
 */

#include <stdlib.h>
#include <wchar.h>
#include <stdio.h>
#include <stdbool.h>
#include "date.h"
#include "dynarray.h"
#include "person.h"
#include "familytree.h"

dynarray* FT;

/*
 *	Luo Singleton Familytreen
 */
void ft_init() { //Ossi
    FT = da_new();
}

/*
 *	Vapauttaa FamilyTreen
 */
void ft_free() { //Ossi
    person* per = NULL;
    do {
        if (per!=NULL){
            ft_remove_person(per);
        }
        per = da_get(FT,0);
    } while (per!=NULL);
    da_free(FT);
}

/*
 *	Hakee FamilyTreestä personin nimellä
 */
person* ft_get_person_by_name(wchar_t* name) { //Joni
    person lost_person;
    lost_person.name = name;
    int index = da_binsearch(FT, &lost_person, 0, FT->top - 1, per_compare);
    if (index != -1) {
        return (person*) da_get(FT, (unsigned int) index);
    }
    return NULL;
}

/*
 *	Lisää Personin FamilyTreehen
 */
int ft_add_person(wchar_t* name, date birthdate, date deathdate, wchar_t gender) { //Joni
    person* new_person = malloc(sizeof(person));
    if (new_person != NULL) {
        new_person->name = name;
        new_person->birthdate = birthdate;
        new_person->deathdate = deathdate;
        new_person->gender = gender;
        new_person->relations = da_new();

        return da_append_inorder(FT, new_person, per_compare,true);
    }
    return -1;
}

/*
 *	Poistaa personin familytreestä
 */

void ft_remove_person(person* person) { //Joni
    int person_index = da_binsearch(FT, person, 0, FT->top - 1, per_compare);
    if (person_index != -1) {
		for(unsigned int i=0;i<person->relations->top;++i) {
			per_remove_relation((relation*)da_get(person->relations,i));
		}
        per_free(da_remove(FT, person_index));
    }
}

/*
 *	Tarkistaa onko henkilö lisätty FamilyTreehen
 */
bool ft_person_exists(person* person) { //Joni
    int person_index = da_binsearch(FT, person, 0, FT->top - 1, per_compare);
    if (person_index != -1) {
        return true;
    }
    return false;
}
